/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.web.misc.cg;

import com.fasterxml.jackson.databind.node.ObjectNode;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.URL;

import javax.validation.constraints.*;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;

/**
 * @author vacoor
 */
public abstract class Validations {

    /*
    bool     --> checkbox
    enum     --> select
    number/string,date           --> input
    richtext       --> textarea
    */

    static abstract class ClassSwitch<T> {
        public final T doSwitch(Class<?> clazz) {
            if (int.class.equals(clazz)) {
                return caseInteger();
            }
            return defaultCase();
        }

        protected T caseBoolean() {
            return defaultCase();
        }

        protected T caseCharacter() {
            return defaultCase();
        }

        protected T caseByte() {
            return defaultCase();
        }

        protected T caseShort() {
            return defaultCase();
        }

        protected T caseInteger() {
            return defaultCase();
        }

        protected T caseFloat() {
            return defaultCase();
        }

        protected T caseDouble() {
            return defaultCase();
        }

        protected T caseBigInteger() {
            return defaultCase();
        }

        protected T caseBigDecimal() {
            return defaultCase();
        }

        protected T caseDate() {
            return defaultCase();
        }

        protected T caseString() {
            return defaultCase();
        }

        protected T caseEnum() {
            return defaultCase();
        }

        protected T defaultCase() {
            return null;
        }

        protected ClassSwitch() {
        }
    }

    String xx(Class<?> type, String[] config) {
        return new ClassSwitch<String>() {
            @Override
            protected String caseBoolean() {
                return super.caseBoolean();
            }

            protected String caseCharacter() {
                return super.caseCharacter();
            }

            @Override
            protected String caseByte() {
                return caseShort();
            }

            @Override
            protected String caseShort() {
                return caseInteger();
            }

            @Override
            protected String caseInteger() {
                return caseFloat();
            }

            @Override
            protected String caseFloat() {
                return caseDouble();
            }

            @Override
            protected String caseDouble() {
                return caseBigDecimal();
            }

            @Override
            protected String caseBigInteger() {
                return caseBigDecimal();
            }

            @Override
            protected String caseBigDecimal() {
                return "<input type=\"text\">";
            }

            @Override
            protected String caseDate() {
                return "<input type=\"text\">";
            }

            @Override
            protected String caseString() {
                return "<input type=\"text\">";
            }

            @Override
            protected String defaultCase() {
                return super.defaultCase();
            }
        }.doSwitch(type);
    }


    public static <E extends AnnotatedElement & Member> void buildJqueryValidationRules(ObjectNode rulesNode, E[] elements) {
        for (E e : elements) {
            ObjectNode rule = rulesNode.putObject(e.getName());
            if (e.isAnnotationPresent(NotNull.class)) {
                rule.put("required", true);
            }
            Size size = e.getAnnotation(Size.class);
            if (null != size) {
                rule.put("minlength", size.min());
                rule.put("maxlength", size.max());
            }
            //
            Min min = e.getAnnotation(Min.class);
            if (null != min) {
                rule.put("digits", true);
                rule.put("min", min.value());
            }
            Max max = e.getAnnotation(Max.class);
            if (null != max) {
                rule.put("digits", true);
                rule.put("max", max.value());
            }
            DecimalMin decimalMin = e.getAnnotation(DecimalMin.class);
            if (null != decimalMin) {
                rule.put("digits", true);
                rule.put("min", decimalMin.value());
            }
            DecimalMax decimalMax = e.getAnnotation(DecimalMax.class);
            if (null != decimalMax) {
                rule.put("digits", true);
                rule.put("max", decimalMax.value());
            }

            Pattern pattern = e.getAnnotation(Pattern.class);
            if (null != pattern) {
                String regexp = pattern.regexp();
                rule.put("pattern", regexp);
            }
            Digits digits = e.getAnnotation(Digits.class);
            if (null != digits) {
                int fraction = digits.fraction();
                if (0 == fraction) {
                    rule.put("digits", true);
                } else {
                    rule.put("number", true);
                }
            }


            // hibernate validator
            if (e.isAnnotationPresent(NotEmpty.class)) {
                rule.put("required", true);
            }
            if (e.isAnnotationPresent(Email.class)) {
                rule.put("email", true);
            }
            if (e.isAnnotationPresent(URL.class)) {
                rule.put("url", true);
            }
            Length length = e.getAnnotation(Length.class);
            if (null != length) {
                rule.put("minlength", length.min());
                rule.put("maxlength", length.max());
            }
        }
    }

}
